package com.boatAnchorAssistant.service.repository.impl;

import cn.hutool.core.collection.CollectionUtil;
import com.boatAnchorAssistant.pojo.entity.Device;
import com.boatAnchorAssistant.pojo.entity.User;
import com.boatAnchorAssistant.pojo.exception.user.UserNumberRepeatException;
import com.boatAnchorAssistant.pojo.exception.user.UserPhoneRepeatException;
import com.boatAnchorAssistant.pojo.vo.user.GetUserListByRoleVo;
import com.boatAnchorAssistant.pojo.vo.user.GetUserListVo;
import com.boatAnchorAssistant.service.mapper.UserMapper;
import com.boatAnchorAssistant.service.repository.in.UserRepository;
import com.boatAnchorAssistant.service.utils.StringUtil;
import nirvana.core.exceptions.BizException;
import nirvana.core.repository.Repository;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import com.boatAnchorAssistant.pojo.dto.user.*;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

/**
 * 【描 述】：
 * 【环 境】：J2SE
 * 【详 细】：
 */
@Service
public class UserRepositoryImpl extends Repository<UserMapper, User> implements UserRepository {

    private static final String RANDOM_CODE = "randomCode_";

    private final UserMapper mapper;

    private final StringRedisTemplate stringRedisTemplate;

    public UserRepositoryImpl(UserMapper mapper, StringRedisTemplate stringRedisTemplate) {
        this.mapper = mapper;
        this.stringRedisTemplate = stringRedisTemplate;
    }


    /**
     * 在添加用户签进行校验
     * <p>
     * 校验账号 邮箱 手机号是否在同一部门下有重复
     *
     * @param user
     * @return
     */
    @Override
    public User createToBefore(User user) {
        String account = user.getAccount();
        String email = user.getEmail();
        String phone = user.getPhone();
        String number = user.getNumber();


        User po = null;
        User byPo = null;


        //校验工号
        po = new User();
        po.setNumber(number);
        byPo = getByEntity(po);

        if (byPo != null) {
            throw new UserNumberRepeatException();
        }

        //校验邮箱
        po = new User();
        po.setEmail(email);
        byPo = getByEntity(po);

        if (byPo != null) {
            throw new BizException("用户邮箱不能重复");
        }


        //校验账号
        po = new User();
        po.setAccount(account);
        byPo = getByEntity(po);

        if (byPo != null) {
            throw new BizException("账号不能重复");
        }


        //校验手机号
        po = new User();
        po.setPhone(phone);
        byPo = getByEntity(po);

        if (byPo != null) {
            throw new UserPhoneRepeatException();
        }

        return user;
    }


    /**
     * 校验用户的账号，邮箱和电话
     * <p>
     * 在修改后是否会与其他同租户下的用户有冲突
     * <p>
     * 先检查是否和原数据有变化
     *
     * @param user
     * @return
     */
    @Override
    public User editToBefore(User user) {
        Long id = user.getId();

        //会和原本的数据比较
        Long tenantId = user.getTenantId();
        String account = user.getAccount();
        String email = user.getEmail();
        String phone = user.getPhone();
        String number = user.getNumber();
        Boolean isSystem = user.getIsSystem();

        User po = null;
        User byPo = null;




        //校验工号
        po = new User();
        po.setNumber(number);
        byPo = getByEntity(po);

        if (byPo != null && !byPo.getId().equals(id)) {
            throw new UserNumberRepeatException();
        }


        //校验邮箱
        po = new User();
        po.setEmail(email);
        byPo = getByEntity(po);

        if (byPo != null && !byPo.getId().equals(id)) {
            throw new BizException("用户邮箱不能重复");
        }


        //校验账号
        po = new User();
        po.setAccount(account);
        byPo = getByEntity(po);

        if (byPo != null && !byPo.getId().equals(id)) {
            throw new BizException("账号不能重复");
        }


        //校验手机号
        po = new User();
        po.setPhone(phone);
        byPo = getByEntity(po);

        if (byPo != null && !byPo.getId().equals(id)) {
            throw new UserPhoneRepeatException();
        }


        return super.editToBefore(user);
    }


    /**
     * 搜索用户
     *
     * @param dto
     * @return
     */
    @Override
    public Page<User> selectUser(SelectUserDto dto) {

        return mapper.selectUser(dto);
    }

    /**
     * 获取用户角色绑定列表
     *
     * @param dto
     * @return
     */
    @Override
    public Page<GetUserListByRoleVo> getUserRoleBindList(SelectUserRoleBindDto dto) {
        return mapper.getUserRoleBindList(dto);
    }

    /**
     * 批量删除用户
     *
     * @param idList
     */
    @Override
    public void bathRemoveUser(List<Long> idList) {
        if (CollectionUtils.isEmpty(idList)) {
            return;
        }
        mapper.bathRemoveUser(idList);
    }

    /**
     * 批量移动用户到其他部门下
     *
     * @param dto
     */
    @Override
    public void bathMoveUser(MoveUserDto dto) {
        List<Long> departmentIds = dto.getDepartmentIds();
        if (CollectionUtils.isEmpty(departmentIds)) {
            return;
        }
        mapper.bathMoveUser(dto);
    }

    /**
     * 获取企业下所有用户的id列表
     *
     * @param tenantId
     * @return
     */
    @Override
    public List<Long> getUserIdListByTenantId(Long tenantId) {
        return mapper.getUserIdListByTenantId(tenantId);
    }

    /**
     * 获取部门下的用户
     *
     * @param dto
     * @return
     */
    @Override
    public Page<GetUserListVo> getUserListByDepartment(SelectUserDto dto) {
        if (!StringUtils.hasText(dto.getName())) {
            dto.setName(null);
        }

        return mapper.getUserListByDepartment(dto);
    }

    /**
     * 根据账号获取用户
     *
     * @param account
     * @param tenantId
     * @return
     */
    @Override
    public User getUserByAccount(String account, Long tenantId) {
        User t = new User();
        t.setAccount(account);
        t.setTenantId(tenantId);
        return getByEntity(t);
    }

    @Override
    public Map<Long, User> getMap(List<Long> ids) {
        Map<Long, User> map = new HashMap<>();

        if (CollectionUtil.isNotEmpty(ids)) {
            List<User> list =listByIds(ids);
            if (CollectionUtil.isNotEmpty(list)) {
                map = list.stream().collect(Collectors.toMap(User::getId, pojo -> pojo));
            }
        }
        return map;
    }

}